package io.keen.client.java;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

public class RamEventStore implements KeenEventStore {
    private Map<String, List<Long>> collectionIds = new HashMap();
    private Map<Long, String> events = new HashMap();
    private int maxEventsPerCollection = 10000;
    private long nextId = 0;

    public synchronized Object store(String projectId, String eventCollection, String event) throws IOException {
        long id;
        String key = String.format(Locale.US, "%s$%s", new Object[]{projectId, eventCollection});
        List<Long> collectionEvents = (List) this.collectionIds.get(key);
        if (collectionEvents == null) {
            collectionEvents = new ArrayList();
            this.collectionIds.put(key, collectionEvents);
        }
        while (collectionEvents.size() >= this.maxEventsPerCollection) {
            this.events.remove(Long.valueOf(((Long) collectionEvents.remove(0)).longValue()));
        }
        id = getNextId();
        this.events.put(Long.valueOf(id), event);
        collectionEvents.add(Long.valueOf(id));
        return Long.valueOf(id);
    }

    public synchronized String get(Object handle) throws IOException {
        return (String) this.events.get(handleToId(handle));
    }

    public synchronized void remove(Object handle) throws IOException {
        this.events.remove(handleToId(handle));
    }

    public synchronized Map<String, List<Object>> getHandles(String projectId) throws IOException {
        Map<String, List<Object>> result;
        result = new HashMap();
        for (Entry<String, List<Long>> entry : this.collectionIds.entrySet()) {
            String key = (String) entry.getKey();
            if (key.startsWith(projectId)) {
                String eventCollection = key.substring(projectId.length() + 1);
                List<Long> ids = (List) entry.getValue();
                List<Object> handles = new ArrayList();
                Iterator<Long> iterator = ids.iterator();
                while (iterator.hasNext()) {
                    Long id = (Long) iterator.next();
                    if (this.events.get(id) == null) {
                        iterator.remove();
                    } else {
                        handles.add(id);
                    }
                }
                if (handles.size() > 0) {
                    result.put(eventCollection, handles);
                }
            }
        }
        return result;
    }

    private long getNextId() {
        if (((long) this.events.size()) > Long.MAX_VALUE) {
            throw new IllegalStateException("Event store exceeded maximum size");
        }
        long id = this.nextId;
        while (this.events.get(Long.valueOf(id)) != null) {
            id++;
        }
        this.nextId = id + 1;
        return id;
    }

    private Long handleToId(Object handle) {
        if (handle instanceof Long) {
            return (Long) handle;
        }
        throw new IllegalArgumentException("Expected handle to be a Long, but was: " + handle.getClass().getCanonicalName());
    }
}
